package cn.com.bluemoon.daps.sync.core.sync.sql;

import cn.com.bluemoon.daps.common.sql.SqlScriptUtils;
import cn.com.bluemoon.daps.common.toolkit.BmAssetUtils;
import cn.com.bluemoon.daps.model.entity.DapDataModelSubordinateKey;
import cn.com.bluemoon.daps.model.entity.DapDataModelTableField;
import cn.com.bluemoon.daps.sync.base.ModifyType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.MySqlDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.MysqlColumnDefinition;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Jarod.Kong
 **/
public abstract class DdlSql {

    protected static final MyIndexTypeIntegerStringConverter INDEX_TYPE_CONVERTER = new MyIndexTypeIntegerStringConverter();
    protected static final MyIndexMethodIntegerStringConverter INDEX_METHOD_CONVERTER = new MyIndexMethodIntegerStringConverter();

    protected boolean addBlackQuote;

    /**
     * 适配历史
     *
     * @param comment 注释
     * @return 格式化
     */
    public static String formatComment0(String comment) {
        return SqlScriptUtils.formatComment(comment);
    }

    /**
     * 排除comment中的单引号
     *
     * @param comment x
     * @return 格式化结果
     */
    public String formatComment(String comment) {
        return SqlScriptUtils.formatComment(comment);
    }

    /**
     * 不考虑
     * <pre>
     *     modifyType 类型
     *     level      级别
     * </pre>
     * 获取字段定义
     *
     * @param newF dao bean
     * @return 获取字段定义
     */
    public MysqlColumnDefinition getMysqlColumnDefinition(DapDataModelTableField newF) {
        return getMysqlColumnDefinition(newF, null, null);
    }

    /**
     * 列定义
     *
     * @param newF       dao bean
     * @param modifyType 类型
     * @param level      级别
     * @return 获取字段定义
     */
    public MysqlColumnDefinition getMysqlColumnDefinition(DapDataModelTableField newF,
                                                          ModifyType modifyType, ModifyType.ModifyLevel level) {
        MysqlColumnDefinition colDef = new MysqlColumnDefinition();
        colDef.setColumnName(newF.getFieldName());
        colDef.setAutoIncrement(isOne(newF.getAutoIncrement()));
        if (colDef.isAutoIncrement()) {
            // 为自增取自增初始值
            colDef.setAutoIncrementInitValue(newF.getAutoIncrDefaultValue());
        }
        colDef.setDefaultValue(newF.getDefaultValue());
        colDef.setNotNull(isOne(newF.getNotNull()));
        colDef.setUnSigned(isOne(newF.getUnSigned()));
        colDef.setZerofill(isOne(newF.getZeroFill()));//2021年7月14日修复字段zerofill属性
        colDef.setComment(formatComment(newF.getComment()));
        // fixed [2021-06-07 10:18:40] [42000][1068] Multiple primary key defined 针对表中已存在的主键，不可在修改字段时候进行primary key
        if (ModifyType.ALTER.equals(modifyType) && ModifyType.ModifyLevel.FIELD.equals(level)) {
            colDef.setPrimaryKey(false);
        } else {
            colDef.setPrimaryKey(isOne(newF.getPrimaryKey()));
        }
        MySqlDataType mySqlDataType = new MySqlDataType();
        mySqlDataType.setName(newF.getDataType());
        mySqlDataType.setLength(newF.getLength());
        mySqlDataType.setScale(newF.getDecimalLength());
        colDef.setDataType(mySqlDataType);
        return colDef;
    }

    protected boolean isOne(Integer i) {
        return (i != null) && (i == 1);
    }

    /**
     * 包addBlackQuote
     *
     * @param str s
     * @return s
     */
    public String wrapperBlackQuote(String str) {
        return "`" + str + "`";
    }

    public String wrapperBlackQuoteIfAddBlackQuote(String str) {
        return addBlackQuote ? wrapperBlackQuote(str) : str;
    }

    /**
     * 适配前缀索引字段
     */
    protected List<String> getIndexFieldInfo(DapDataModelSubordinateKey newI) {
        String[] fieldNamesSplit = newI.getFieldNamesSplit();
        String[] fieldNameSubPartsArr = newI.fieldNameSubPartsArr();
        BmAssetUtils.isTrue(fieldNamesSplit.length > 0, "索引字段列表不可为空");
        List<String> fields = new ArrayList<>(fieldNamesSplit.length);
        int fieldSubPartLength = fieldNameSubPartsArr.length;
        for (int i = 0; i < fieldNamesSplit.length; i++) {
            String fieldName = fieldNamesSplit[i];
            // 防越界，要是长度定义溢出的就直接忽略长度
            if (i < fieldSubPartLength) {
                String fieldSubPart = fieldNameSubPartsArr[i];
                if (StringUtils.isNotBlank(fieldSubPart) &&
                        StringUtils.isNumeric(fieldSubPart) &&
                        !"0".equals(fieldSubPart)) {
                    fields.add(String.format("%s(%s)", fieldName, fieldSubPart));
                } else {
                    fields.add(fieldName);
                }
            } else {
                fields.add(fieldName);
            }
        }
        return fields.stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
    }

    /**
     * 增肌控制
     *
     * @param addBlackQuote a
     */
    public void setAddBlackQuote(boolean addBlackQuote) {
        this.addBlackQuote = addBlackQuote;
    }
}
